package top.jlzhou.tools;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <pre>网络工具类
 * 	用于获取ip地址和MAC地址，以及端口检查
 * </pre>
 * @ClassName	top.jlzhou.tools.NetUtil
 * @author	J.L.Zhou
 * @date	2019年3月9日 下午6:45:36
 * @version 	V1.0
 * @Copyright	2019 jlzhou.top Inc. All rights reserved. 
 * 	注意：本内容仅限于公司内部传阅，禁止外泄以及用于其他的商业目
 */
public class NetUtil {

	NetUtil() {}

	/**
	 * 获取本机所有IP
	 * 
	 * @throws SocketException
	 */
	public List<String> getIPList() throws SocketException {
		List<String> res = new ArrayList<String>();
		Enumeration<?> netInterfaces;

		netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
		while (netInterfaces.hasMoreElements()) {
			NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
			Enumeration<InetAddress> nii = ni.getInetAddresses();
			while (nii.hasMoreElements()) {
				ip = (InetAddress) nii.nextElement();
				res.add(ip.getHostAddress());
				
			}
		}
		return res;
	}
	
	/**
	 * 获取本机所有的IPv4
	 * @return
	 * @throws SocketException
	 */
	public List<String> getIPv4List() throws SocketException {
		List<String> res = new ArrayList<String>();
		Enumeration<?> netInterfaces;

		netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
		while (netInterfaces.hasMoreElements()) {
			NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
			Enumeration<InetAddress> nii = ni.getInetAddresses();
			while (nii.hasMoreElements()) {
				ip = (InetAddress) nii.nextElement();
				if(ip.getHostAddress().indexOf(":")==-1){
					res.add(ip.getHostAddress());
				}
			}
		}
		return res;
	}
	
	public List<String> getIPv6List() throws SocketException {
		List<String> res = new ArrayList<String>();
		Enumeration<?> netInterfaces;

		netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
		while (netInterfaces.hasMoreElements()) {
			NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
			Enumeration<InetAddress> nii = ni.getInetAddresses();
			while (nii.hasMoreElements()) {
				ip = (InetAddress) nii.nextElement();
				if(ip.getHostAddress().indexOf(":")>-1){
					res.add(ip.getHostAddress());
				}
			}
		}
		return res;
	}
	
	

	/**
	 * 获取当前主要的IP
	 * 
	 * @return
	 * @throws UnknownHostException 
	 */
	public String getIP() throws UnknownHostException {
		return InetAddress.getLocalHost().getHostAddress();
	}
	
	/**
	 * 获取主要的MAC
	 * @return
	 * @throws UnknownHostException 
	 * @throws SocketException 
	 * @throws UnknownHostException
	 */
	public String getMAC() throws SocketException, UnknownHostException {
		NetworkInterface networkInterface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
        byte[] bytes = networkInterface.getHardwareAddress();
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            if (i != 0) {
                stringBuffer.append("-");
            }
            int tmp = bytes[i] & 0xff; // 字节转换为整数
            String str = Integer.toHexString(tmp);
            if (str.length() == 1) {
                stringBuffer.append("0" + str);
            } else {
                stringBuffer.append(str);
            }
        }
        String mac = stringBuffer.toString().toUpperCase();  
        return mac;
	}
	
	/**
	 * 获取ip和MAC地址对应关系
	 * @return
	 * @throws SocketException
	 */
	public Map<String,String> getIP2MAC() throws SocketException{
		Map<String,String> map = new HashMap<String, String>();
		Enumeration<?> netInterfaces;

		netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
		while (netInterfaces.hasMoreElements()) {
			NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
			Enumeration<InetAddress> nii = ni.getInetAddresses();
			while (nii.hasMoreElements()) {
				ip = (InetAddress) nii.nextElement();
				NetworkInterface networkInterface = NetworkInterface.getByInetAddress(ip);
		        byte[] bytes = networkInterface.getHardwareAddress();
		        if(bytes==null){
		        	continue;
		        }
		        StringBuffer stringBuffer = new StringBuffer();
		        for (int i = 0; i < bytes.length; i++) {
		            if (i != 0) {
		                stringBuffer.append("-");
		            }
		            int tmp = bytes[i] & 0xff; // 字节转换为整数
		            String str = Integer.toHexString(tmp);
		            if (str.length() == 1) {
		                stringBuffer.append("0" + str);
		            } else {
		                stringBuffer.append(str);
		            }
		        }
		        String mac = stringBuffer.toString().toUpperCase();
		        map.put(ip.getHostAddress(), mac);
			}
		}
		return map;
	}

	/**
     * 检查ip地址或主机能否绑定端口
     * @param host IP
     * @param port
     * @return
     */
    public boolean isPortAvailable(String host, int port){
    	try{
	        Socket s = new Socket();
	        s.bind(new InetSocketAddress(host, port));
	        s.close();
	        return true;
    	}catch(Exception ex){
    		return false;
    	}
    }
    
    
    /**
     * 获取所有的网卡物理地址
     * @return
     * @throws SocketException
     */
    public List<String> getMACList() throws SocketException{
    	List<String> list = new ArrayList<String>();
    	Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
        while (enumeration.hasMoreElements()) {
            StringBuffer stringBuffer = new StringBuffer();
            NetworkInterface networkInterface = enumeration.nextElement();
            if (networkInterface != null) {
                byte[] bytes = networkInterface.getHardwareAddress();
                if (bytes != null) {
                    for (int i = 0; i < bytes.length; i++) {
                        if (i != 0) {
                            stringBuffer.append("-");
                        }
                        int tmp = bytes[i] & 0xff; // 字节转换为整数
                        String str = Integer.toHexString(tmp);
                        if (str.length() == 1) {
                            stringBuffer.append("0" + str);
                        } else {
                            stringBuffer.append(str);
                        }
                    }
                    String mac = stringBuffer.toString().toUpperCase();  
                    list.add(mac);
                }
            }
        }
        return list;
    }
}
